package pl.edu.agh.ssm.monitor.listeners;

import pl.edu.agh.ssm.monitor.SessionMonitorApp;
import pl.edu.agh.ssm.monitor.data.Packet;
import pl.edu.agh.ssm.monitor.data.Session;
import pl.edu.agh.ssm.monitor.data.SessionDataContainer;
import pl.edu.agh.ssm.monitor.data.SessionDescription;
import pl.edu.agh.ssm.monitor.data.SessionType;
import pl.edu.agh.ssm.monitor.data.SessionDescription.MediaDescription;
import pl.edu.agh.ssm.monitor.net.PacketReceiver;
import pl.edu.agh.ssm.monitor.parsers.sdp.InvalidDataException;
import pl.edu.agh.ssm.monitor.parsers.sdp.SDPParser;
import pl.edu.agh.ssm.monitor.utils.PacketListenersUtils;

public class SDPProtocolListener implements SessionListener {

	private int priority;
	private SessionDataContainer<Session> sessions = null;
	private SDPParser parser;
	private PacketReceiver receiver;

	public SDPProtocolListener(PacketReceiver receiver) {
		this.receiver = receiver;
		sessions = SessionMonitorApp.getApplication().getManager()
				.createContainer(Session.class);
		parser = new SDPParser();
	}

	@Override
	public void processPacket(Packet packet) {
		try {
			//First 8 bytes are from SAP protocol and are not needed to understand SDP
			SessionDescription sessionDescription = parser.parse(new String(
					packet.getData(), 8, packet.getData().length - 8));
			// Check if session is already present
			
			Session session = sessions.get(
					generateID(sessionDescription.getOwner()));
			// if no - add new session
			if (session == null) {
				session = new Session(generateID(sessionDescription.getOwner()));
				session.setSessionType(SessionType.SDP_SESSION);
				session.setSessionDesc("SDP:" + sessionDescription.getName());
				sessions.add(session);
				// add data listeners
				for (MediaDescription mediaDescription : sessionDescription
						.getMediaDescriptions()) {
					String address = mediaDescription.getMediaAddress();
					int port = mediaDescription.getMediaPort();
					new PacketListenersUtils().createRtpAndRTCPDataListeners(this, session, receiver,
							this.priority - 1, address, port, null, sessionDescription.getRtpmap(), null, 0);
				}
			}
			session.setSessionDescription(sessionDescription);
			session.setSessionDesc("SDP:" + sessionDescription.getName());
			session.setLastSDPTime(System.currentTimeMillis());
			sessions.update(session);
		} catch (InvalidDataException e) {
			e.printStackTrace();
		}
	}

	public int getPriority() {
		return priority;
	}

	public void setPriority(int priority) {
		this.priority = priority;
	}

	private String generateID(String owner) {
		String[] tmp = owner.split(" ");
		return "SDP_" + tmp[0] + " " + tmp[1];
	}
}